#ifndef UTILS_H
#define UTILS_H

#include <string>
#include <vector>
#include <map>

//--------------------------------------------------------------------//
// estruturas usadas para acomodar dados vindos do arquivo de entrada //
typedef struct Maquina{
    std::string nome_;
    std::string path_;
    std::string estado_inicial_;
    std::string estado_final_;
}Maquina;

typedef struct Regra{
    std::string atr1_;
    std::string atr2_;
    std::string atr3_;
    std::vector<std::string> vetor_estados_;
}Regra;
//--------------------------------------------------------------------//


//Estrutura de quadrupla
typedef struct Quadrupla{
    std::string atr1_;
    std::string atr2_;
    std::string atr3_;
    std::string atr4_;
}Quadrupla;

//--------------------------------------------------------------//
// Variaveis reponsaveis por salvar dados do arquivo de entrada //
extern int numero_max_iteracoes;
extern std::map<std::string, std::vector<Maquina*> > map_maquinas;
extern std::map<std::string, std::vector<Regra*> > map_regras;
extern std::map<std::string, std::vector<std::string> > map_alfabeto;
//--------------------------------------------------------------//


extern std::map<std::string,std::ofstream*> banco_de_mts;
extern std::map<std::string,std::ofstream*> banco_de_dts;

//Arquivo de saida
//extern std::ofstream arquivo_output;

/*
Funcao para ler o arquivo de entrada e salvar na memória os dados
usando as estruturas e variáveis definidas acima */
void LerArquivo(std::string &dt_nome, std::string &path_arquivo);
void CriarArquivoOutput(std::string &nome_arquivo, std::string &path);
void FecharArquivoOutput(std::ofstream *arquivo_output);
//usar o vetor de maquinas, ler todas as quadruplas de cada maquina e salva
void ProcessarMaquinas(std::string &dt_nome,std::ofstream *arquivo_output);
/*ligar estados de maquinas diferentes baseado nas regras definadas no arquivo de entrada.
Isso implica em criar novas quadruplas claro
*/
void FazerTransicoes(std::string &dt_nome, std::ofstream *arquivo_output);
void ParseColchetes(Regra *r);
void SalvarAlfabeto(std::string &dt_nome, Maquina *m);
void AdicionarElemento(std::string &dt_nome, std::string &elemento); // adiciona elemento ao alfabeto
void AdicionarHeader(std::string &dt_nome, std::ofstream *arquivo_output);
//------------------------------------------------------------------------//

void DtParaMt(std::string &nome, std::string &dt_path); //cria arquivo .mt a partir de um .dt que só inclui .mt
void ProcessarDt(std::string &dt_nome, std::string &dt_path);
void DetectarEstadoFinaleInicial(Maquina* m);
bool EhNumero(std::string &str);

#endif // UTILS_H
